﻿/**********************************************************
 ●项目：Smartkernel
 ●公司：智能核心信息技术研发中心
 ●作者：曹艳白
 ●邮箱：caoyanbai@gmail.com
 ●创建：2008-08-10
 ●版本：1.0
**********************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Smartkernel.Caching
{
    /// <summary>
    /// 内存高速缓存类
    /// </summary>
    public static partial class SmartMemoryCacher
    {
        #region 加入缓存项方法
        /// <summary>
        /// 加入缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        /// <param name="cacheTime">对象的缓存时间，小于等于0表示永久，其他值表示缓存的秒数</param>
        /// <param name="refreshCreateTime">是否更新创建时间，如果为true则更新，每次对象被访问都会刷新创建时间为当前时间，会影响到超时清理条件</param>
        /// <param name="minCounter">在指定缓存时间内，调用次数小于这个值的将被清理，小于等于0代表此条件不起作用</param>
        public static void Add(string category, string key, object value, int cacheTime, bool refreshCreateTime, int minCounter)
        {
            SmartCacherValue<object> smartCacherValue = new SmartCacherValue<object>(value, cacheTime, refreshCreateTime, minCounter);
            SmartCacherKey<string> smartCacherKey = CreateKey(category, key);
            lock (dictionary)
            {
                dictionary.Add(smartCacherKey, smartCacherValue);
            }
        }
        /// <summary>
        /// 加入默认分类缓存项
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        /// <param name="cacheTime">对象的缓存时间，小于等于0表示永久，其他值表示缓存的秒数</param>
        /// <param name="refreshCreateTime">是否更新创建时间，如果为true则更新，每次对象被访问都会刷新创建时间为当前时间，会影响到超时清理条件</param>
        /// <param name="minCounter">在指定缓存时间内，调用次数小于这个值的将被清理，小于等于0代表此条件不起作用</param>
        public static void Add(string key, object value, int cacheTime, bool refreshCreateTime, int minCounter)
        {
            Add(defaultCategory, key, value, cacheTime, refreshCreateTime, minCounter);
        }
        /// <summary>
        /// 插入超时缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        /// <param name="cacheTime">对象的缓存时间，小于等于0表示永久，其他值表示缓存的秒数</param>
        /// <param name="refreshCreateTime">是否更新创建时间，如果为true则更新，每次对象被访问都会刷新创建时间为当前时间，会影响到超时清理条件</param>
        public static void Add(string category, string key, object value, int cacheTime, bool refreshCreateTime)
        {
            Add(category, key, value, cacheTime, refreshCreateTime, 0);
        }
        /// <summary>
        /// 插入默认分类超时缓存项
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        /// <param name="cacheTime">对象的缓存时间，小于等于0表示永久，其他值表示缓存的秒数</param>
        /// <param name="refreshCreateTime">是否更新创建时间，如果为true则更新，每次对象被访问都会刷新创建时间为当前时间，会影响到超时清理条件</param>
        public static void Add(string key, object value, int cacheTime, bool refreshCreateTime)
        {
            Add(defaultCategory, key, value, cacheTime, refreshCreateTime, 0);
        }
        /// <summary>
        /// 加入永久缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        public static void Add(string category, string key, object value)
        {
            Add(category, key, value, 0, false, 0);
        }
        /// <summary>
        /// 加入默认分类永久缓存项
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">缓存项</param>
        public static void Add(string key, object value)
        {
            Add(defaultCategory, key, value, 0, false, 0);
        }
        #endregion

        #region 公共方法，属性和字段
        /// <summary>
        /// 获取缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        /// <returns>缓存项</returns>
        public static object GetValue(string category, string key)
        {
            if (ContainsKey(category, key))
            {
                return dictionary[CreateKey(category, key)].Value;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 获取默认分类缓存项
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>缓存项</returns>
        public static object GetValue(string key)
        {
            return GetValue(defaultCategory, key);
        }
        /// <summary>
        /// 判断缓存项是否存在
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        /// <returns>判断的结果，true表示存在，false表示不存在</returns>
        public static bool ContainsKey(string category, string key)
        {
            return dictionary.ContainsKey(CreateKey(category, key));
        }
        /// <summary>
        /// 判断默认分类缓存项是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>判断的结果，true表示存在，false表示不存在</returns>
        public static bool ContainsKey(string key)
        {
            return ContainsKey(defaultCategory, key);
        }
        /// <summary>
        /// 删除缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">键</param>
        public static void Remove(string category, string key)
        {
            lock (dictionary)
            {
                dictionary.Remove(CreateKey(category, key));
            }
        }
        /// <summary>
        /// 删除默认分类缓存项
        /// </summary>
        /// <param name="key">键</param>
        public static void Remove(string key)
        {
            Remove(defaultCategory, key);
        }
        /// <summary>
        /// 清空指定分类的全部缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        public static void Clear(string category)
        {
            var linq = from item in dictionary where item.Key.Category == category select item.Key;
            lock (dictionary)
            {
                List<SmartCacherKey<string>> list = linq.ToList<SmartCacherKey<string>>();
                list.ForEach(item => dictionary.Remove(item));
            }
        }
        /// <summary>
        /// 清空默认分类的全部缓存项
        /// </summary>
        public static void Clear()
        {
            Clear(defaultCategory);
        }
        /// <summary>
        /// 清空全部分类缓存项
        /// </summary>
        public static void ClearAll()
        {
            lock (dictionary)
            {
                dictionary.Clear();
            }
        }
        /// <summary>
        /// 手工执行清理的功能，清理全部缓存项
        /// </summary>
        public static void CleanAll()
        {
            CleanCallback(new object());
        }
        /// <summary>
        /// 手工执行清理的功能，清理默认分类的全部缓存项
        /// </summary>
        public static void Clean()
        {
            CleanCallback(new object());
        }
        /// <summary>
        /// 手工执行清理的功能，清理指定分类的全部缓存项
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        public static void Clean(string category)
        {
            DateTime now = DateTime.Now;
            var linq = from item in dictionary where item.Value.IsOverdue && item.Key.Category == category select item.Key;
            lock (dictionary)
            {
                List<SmartCacherKey<string>> list = linq.ToList<SmartCacherKey<string>>();
                list.ForEach(item => dictionary.Remove(item));
            }
        }
        #endregion
    }
    public static partial class SmartMemoryCacher
    {
        #region 私有方法，属性和字段
        /// <summary>
        /// 内部缓存器，基于静态字段的实现，应用程序退出时，缓存会清除
        /// </summary>
        private static Dictionary<SmartCacherKey<string>, SmartCacherValue<object>> dictionary = new Dictionary<SmartCacherKey<string>, SmartCacherValue<object>>();
        /// <summary>
        /// 定时器对象
        /// </summary>
        private static Timer timer = new Timer(CleanCallback, null, 0, 60 * 1000);
        /// <summary>
        /// 定时清理程序
        /// </summary>
        /// <param name="o">传递的对象</param>
        private static void CleanCallback(object o)
        {
            DateTime now = DateTime.Now;
            var linq = from item in dictionary where item.Value.IsOverdue select item.Key;
            lock (dictionary)
            {
                List<SmartCacherKey<string>> list = linq.ToList<SmartCacherKey<string>>();
                list.ForEach(item => dictionary.Remove(item));
            }
        }
        /// <summary>
        /// 根据分类和原始键产生实际存储的键
        /// </summary>
        /// <param name="category">缓存所属分类</param>
        /// <param name="key">原始键</param>
        /// <returns>实际存储的键</returns>
        private static SmartCacherKey<string> CreateKey(string category, string key)
        {
            return new SmartCacherKey<string>(category, key);
        }
        /// <summary>
        /// 默认所属分类的名称
        /// </summary>
        private static string defaultCategory = "__SmartMemoryCacher__DefaultCategory";
        #endregion
    }
}
